<?php

/**
*  @package :  class.main
*  @classID :   Action.class.php
*  @author  :  邝达峰
*  @date    : 2017-07-11
*  异常处理继承类
*  该类继承PHP5的 Exception异常处理类
*  Exception类 	主要方法说明
*  getCode()  		  返回传递给构造函数的代码
*  getMessage()		  返回传递给构造函数的消息
*  getFile()		      返回产生异常的代码文件的完整路径
*  getLine()		      返回代码文件中产生异常的代码行号
*  getTrace()		  返回一个包含了产生异常的代码回退路径的数组
*  getTraceAsString()  返回与getTrace()方向相同的信息 该信息将被格式化成一个字符串
*  __toString()		  允许简单地显示一个Exception对象 并且给出以上所有方法可以提供的信息
* 
*/

#加载日志处理类
include_once SYSTEM_CLASS_PATH.'main'.DIRECTORY_SEPARATOR.'Log.class.php';

class BaseException extends Exception
{
	/**
	 +----------------------------------------------------------
	 * 异常类型
	 +----------------------------------------------------------
	 * @var string
	 * @access private
	 +----------------------------------------------------------
	 */
	private $type;
	#是否存在多余调试信息
	private $extra;
	#错误保存路径
	private $sava_path = '';

	/**
	 +----------------------------------------------------------
	 * 架构函数
	 +----------------------------------------------------------
	 * @access public 
	 +----------------------------------------------------------
	 * @param string $message  抛出的异常消息内容
	 * @param int $code  异常代码
	 * @param bool $extra  通过throw_exception抛出的异常要去掉多余的调试信息
	 +----------------------------------------------------------
	 */

	public function __construct($message,$code=0,$extra=false,$savaPath='')
	{
		#继承父类
		parent::__construct($message,$code);
		#返回对象的类名
		$this->type = get_class($this);
		#通过throw_exception抛出的异常要去掉多余的调试信息
		$this->extra = $extra;
		$this->sava_path = $savaPath;
	}

	/**
	 +----------------------------------------------------------
	 * 异常输出 所有异常处理类均通过__toString方法输出错误
	 * 每次异常都会写入系统日志
	 * 该方法可以被子类重载
	 +----------------------------------------------------------
	 * @access public 
	 +----------------------------------------------------------
	 * @return array
	 +----------------------------------------------------------
	 */
	public function __toString()
	{
		#返回一个包含了产生异常的代码回退路径的数组
		$trace = $this->getTrace();
		#通过throw_exception抛出的异常要去掉多余的调试信息
		if($this->extra) {
			array_shift($trace);
		}
		$this->class = $trace[0]['class'];
		$this->function = $trace[0]['function'];
		$this->file = $trace[0]['file'];
		$this->line = $trace[0]['line'];
		$file   =   file($this->file);
		$traceInfo='';
		$time = date("y-m-d H:i:m");
		foreach($trace as $t) {
			$traceInfo .= '['.$time.'] '.$t['file'].' ('.$t['line'].') ';
			$traceInfo .= $t['class'].$t['type'].$t['function'].'(';
			$traceInfo .= implode(', ', $t['args']);
			$traceInfo .=")\n";
		}
		$error['message']   = $this->message;
		$error['type']      = $this->type;
		$error['detail']    = '['.$_REQUEST['module'].' '.$_REQUEST['action'].' '.$_REQUEST['cmd'].']'."\n";
		$error['detail']   .=   ($this->line-2).': '.$file[$this->line-3];
		$error['detail']   .=   ($this->line-1).': '.$file[$this->line-2];
		$error['detail']   .=   '<font color="#FF6600" >'.$this->line.': <b>'.$file[$this->line-1].'</b></font>';
		$error['detail']   .=   ($this->line+1).': '.$file[$this->line];
		$error['detail']   .=   ($this->line+2).': '.$file[$this->line+1];
		$error['class']     =   $this->class;
		$error['function']  =   $this->function;
		$error['file']      = $this->file;
		$error['line']      = $this->line;
		$error['trace']     = $traceInfo;
		#记录系统日志
		$errorStr   = "\n".$GLOBALS['lang']['ERROR_INFO']."[ ".$_REQUEST[MODULE_NAME].' '.$_REQUEST[CONTROLLER_NAME].' '.$_REQUEST[FUNCTION_NAME].' ]'.$this->message."\n";
		if($_SERVER['HTTP_REFERER']){
			$errorStr  .= $GLOBALS['lang']['ERROR_REFF'].$_SERVER['HTTP_REFERER']."\n";
		}
		$errorStr  .= $GLOBALS['lang']['ERROR_URL'].'http://'.$_SERVER['HTTP_HOST'].$_SERVER["REQUEST_URI"]."\n".$_SERVER["SCRIPT_URI"]."\n";
		$errorStr  .= 'HTTP_USER_AGENT：'.$_SERVER['HTTP_USER_AGENT']."\n";
		$errorStr  .= 'IP：'.getClientIp()."\n";
		$errorStr  .= $GLOBALS['lang']['ERROR_TYPE'].$this->type."\n";
		$errorStr  .= $GLOBALS['lang']['ERROR_TRACE']."\n".$traceInfo;
		#写错误日志
		Log::write($errorStr,$this->sava_path);
		#返回日志
		return $error;
	}
}

?>
